import urllib2, urllib, cookielib
import logging
import re
import notify

class WebMail:
    def __init__ (self, name, login_url, map):
        self.name = name
        self.login_url = login_url
        self.login_data = map
        self.cookie_jar = cookielib.CookieJar ()
        self.max_mails = 3
    
    def _opener (self):
        return urllib2.build_opener (urllib2.HTTPCookieProcessor (self.cookie_jar))

    def login (self):
        req = urllib2.Request (url=self.login_url,
                data=urllib.urlencode (self.login_data))

        self.response = self._opener ().open(req)

    def _format (self, new_mails):
        formatted = "- %s\n" % self.name
        for mail in new_mails:
            formatted += '% -20s|% -50s\n' % (str (mail [0][:20]), str (mail [1][:50]))

        return formatted

    def _readMails (self):
        pass

    def unreadMail (self):
        new_mails, num_unread = self._readMails ()
        new_mails = self._format (new_mails)

        if self._notify (new_mails, num_unread):
            return new_mails
        else:
            return False

    def _notify (self, new_mails, num_unread):
        import os
        file = ".mails" + self.name
        if os.path.exists(file):
            logs = open (file, "r")
            if logs.read () == new_mails:
                logs.close ()
                return False
            logs.close ()

        logs = open (file, "w")
        logs.write (new_mails)
        logs.close ()
        notify.notify ("Got %s %s mails" % (num_unread, self.name), new_mails)
        return True

class OWA(WebMail):
    def __init__ (self, name, owa_url, username, password):
        WebMail.__init__ (
                self,
                name,
                owa_url + 'auth/owaauth.dll', 
                {"destination":     owa_url,
                 "flags":           "4",
                 "forcedownlevel":  "0",
                 "isUtf8":          "1",
                 "password":        password,
                 "trusted":         "4",
                 "username":        username})

        self.unread_regex = re.compile ('Inbox </a><span class="unrd">\((\d*)\)</span>')

    def _readMails (self):
        data = self.response.read ()
        num_unread = self.unread_regex.search (data).group (1)

        mail = [
                ['table', [('class', 'mnTbl'), ('cellspacing', '0'), ('cellpadding', '0')]],
                ['td',    [('class', 'cntnttp')]],
                ['div',   [('class', 'cntnt')]],
                ['table', [('class', 'lvw'), ('cellspacing', '0'), ('cellpadding', '0')]],
                ['tr',    [('style', 'font-weight:bold;')]]
        ]

        from HTMLParser import HTMLParser
        class MyHTMLParser(HTMLParser):
            def __init__ (self, struct, max_mails):
                HTMLParser.__init__ (self)
                self.struct = struct
                self.index = 0
                self.stack = []
                self.max_mails = max_mails
                self.new_mails = []

            def handle_starttag(self, tag, attrs):
                found = False
                if self.max_mails <= 0:
                    return

                if tag == self.struct [self.index][0]:
                    if not set (attrs) >= set (self.struct [self.index][1]):
                        return

                    if self.index + 1 >= len (self.struct):
                        logging.debug ("Found")
                        self.mail = []
                        found = True
                    else:
                        self.index += 1

                if found or len (self.stack) > 0:
                    self.stack.append (tag)

            def handle_data (self, data):
                if len (self.stack) > 0:
                    if len (self.mail) <= 2:
                        self.mail.append (data)

            def handle_endtag (self, tag):
                while len (self.stack) > 0:
                    top = self.stack.pop ()
                    logging.debug ("%r tag: %r top: %r" % (self.stack, tag, top))
                    if len (self.stack) == 0:
                        self.new_mails.append (self.mail)
                        self.max_mails -= 1
                    if top == tag:
                        break

        m = MyHTMLParser (mail, self.max_mails)
        m.feed (data)

        return m.new_mails, num_unread

class GMail(WebMail):
    def __init__ (self, username, password):
        WebMail.__init__ (
                self,
                'GMail',
                "https://mail.google.com/mail/feed/atom",
                {'username': username, 'password': password})

    def _opener (self):
        auth_handler = urllib2.HTTPBasicAuthHandler()
        auth_handler.add_password('New mail feed',
                                  self.login_url,
                                  self.login_data ['username'],
                                  self.login_data ['password'])

        return urllib2.build_opener (auth_handler, urllib2.HTTPCookieProcessor (self.cookie_jar))

    def _readMails (self):
        import feedparser
        atom = feedparser.parse(self.response.read ())

        # Mostly pretty printing magic
        new_mails = []
        for i in xrange(len(atom.entries)):
            if i >= self.max_mails:
                break
            new_mails.append ([
                atom.entries[i].title,
                atom.entries[i].author_detail.name])

        return new_mails, len(atom.entries)


def check_mails ():
    mails = [OWA (
                "Office",
                "https://imail.dilithiumnetworks.com/owa/",
                "fasih",
                "fasih"),
            GMail (
                'fasih',
                'fasih')
            ]

    str = ''
    for mail in mails:
        try:
            mail.login ()
            umail = mail.unreadMail ()
            if umail:
                str += umail
        except Exception, ex:
            print "Could not chck %r" % mail.name
            print ex
    return str
